/**
 * 
 */
package com.netscenery.yang.model;

import org.jdom2.Attribute;
import org.jdom2.Element;

import com.netscenery.util.ErrTag;
import com.netscenery.util.XMLTag;
import com.netscenery.yang.YangKeyword;
import com.netscenery.yang.YangStatement;
import com.netscenery.yang.abnf.Parser;
import com.netscenery.yang.abnf.ParserException;
import com.netscenery.yang.abnf.Rule;
import com.netscenery.yang.parser.YangParserException;

/**
 * @author llly
 *
 */
public class LeafRef extends Type {
	private String path;

	/**
	 * @return the path
	 */
	public String getPath() {
		return path;
	}

	/**
	 * @param path the path to set
	 */
	public void setPath(String path) {
		if (!checkPath(path)){
			return;
		}
		this.path = path;
	}
	/**
	 * 
	 * @param path
	 * @return
	 */
	public boolean checkPathExpress(String path){
		try {
			Rule rule = Parser.parse("path-arg", path);
			if (null != rule){
				return true;
			}
			return false;
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println(e.getMessage());
		}
		
		return false;
	}
	
	public boolean checkPath(String path){
		if (null == path){
			return false;
		}
		
		if (this.isDerivedType()){
			return false;
		}
		
		return checkPathExpress(path);
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#validate()
	 */
	@Override
	public Validator validate() {
		Validator validator = new Validator();
		if (!checkPath(this.path)){
			validator.setIsValid(false);
			validator.addMsg(new Message(this,ErrTag.ERROR,"invalid path."));

		}
		Validator sValidator = super.validate();
		validator.copy(sValidator);
		return validator;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#toYang()
	 */
	@Override
	public YangStatement toYang() {
		YangStatement leafref = new YangStatement(YangStatement.YANG_STATEMENT_TYPE,this.name);
		if (null != path){
			YangStatement path = new YangStatement(YangStatement.YANG_STATEMENT_PATH,this.path);
			leafref.addChild(path);
		}
		return leafref;
	}
	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#toYang()
	 */
	@Override
	public Element toYin() {
		Element leafref = new Element(YangStatement.YANG_STATEMENT_TYPE,env.getNs());
		Attribute name = new Attribute(XMLTag.XML_TAG_NAME,this.name);
		leafref.setAttribute(name);
		if (null != path){
			Element path = new Element(YangStatement.YANG_STATEMENT_PATH,env.getNs());
			Attribute value = new Attribute(YangKeyword.VALUE.getKeyword(),this.path);
			path.setAttribute(value);
			leafref.addContent(path);
		}
		return leafref;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#toXML()
	 */
	@Override
	public Element toXML() {
		Element leafref = new Element(XMLTag.XML_TAG_TYPE);
		
		Element type;
		if (this.isDerivedType() == true){
			type = new Element(	XMLTag.XML_TAG_DERIVEDTYPE);
		}
		else {
			type = new Element(XMLTag.XML_TAG_BASETYPE);
		}
		
		type.setText(this.name);
		leafref.addContent(type);
		
		if (null != path){
			Element path = new Element(XMLTag.XML_TAG_PATH);
			path.setText(this.path);
			leafref.addContent(path);
		}
		return leafref;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#readXML(org.jdom2.Element)
	 */
	@Override
	public int readXML(Element element) throws ModelException {
		if (null == element){
			return MODELELEMENT_OK;
		}
	
		if (element.getName().equals(XMLTag.XML_TAG_PATH)){
			this.setPath(element.getText());
		}
		else if (element.getName().equals(XMLTag.XML_TAG_NAME)){
			return MODELELEMENT_OK;
		}
		else {
			return MODELELEMENT_FAIL;
		}
		

		return MODELELEMENT_OK;

	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#readYANG(com.netscenery.modeldesigner.util.YangStatement)
	 */
	@Override
	public int readYANG(YangStatement statement) throws YangParserException {
		if (null == statement){
			return MODELELEMENT_OK;
		}
		if (statement.getKeyword().equals(YangStatement.YANG_STATEMENT_PATH)){
			this.setPath(statement.getArgument());
		}
		else {
			return MODELELEMENT_FAIL;
		}
		

		return MODELELEMENT_OK;
	}
	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#readYANG(com.netscenery.modeldesigner.util.YangStatement)
	 */
	@Override
	public int readYin(Element statement) throws ModelException {
		if (null == statement){
			return MODELELEMENT_OK;
		}
		if (statement.getName().equals(YangStatement.YANG_STATEMENT_PATH)){
			String path = statement.getAttributeValue(YangKeyword.VALUE.getKeyword());
			this.setPath(path);
		}
		else {
			return MODELELEMENT_FAIL;
		}
		

		return MODELELEMENT_OK;
	}
	public static void main(String[] args){
		LeafRef leafRef = new LeafRef();
		leafRef.setPath("/configuration/test[test1=current()/../test2]/test");
	}

}
